package gotcache

import (
	"context"
	"errors"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gcache"
	"github.com/gogf/gf/v2/util/gconv"
	"time"
)

var CacheType = g.Cfg().MustGet(context.Background(), "gToken.system.CacheMode").Int64()

// GetOrSetFunc 根据配置文件里的设置：gToken.system.CacheMode，自动支持MemCache, Redis两种缓存方案。
func GetOrSetFunc(ctx context.Context, cacheKey string, f gcache.Func, timeOut time.Duration) (value string) {
	switch CacheType {
	case 1: // MemCache
		cacheValue, err := gcache.GetOrSetFunc(ctx, cacheKey, f, timeOut)
		if err != nil {
			g.Log().Error(ctx, "[MemCache]cache error", err)
		}
		return gconv.String(cacheValue)
	case 2: // Redis
		cacheValue, err := g.Redis().Do(ctx, "GET", cacheKey)
		if err != nil {
			g.Log().Error(ctx, "[Redis]cache error", err)
		}
		if cacheValue != nil {
			return gconv.String(cacheValue)
		}
	}
	cacheValue, _ := f(ctx)
	value = gconv.String(cacheValue)
	//g.Redis().DoWithTimeout(timeOut, "SET", cacheKey, value)
	g.Redis().Do(ctx, "SETEX", cacheKey, value, timeOut) //TommySUN SETEX设置秒，SETPX：millisecond
	return value
}

// RemoveCache 根据配置文件里的设置：gToken.system.CacheMode，自动支持MemCache, Redis两种缓存删除。
func RemoveCache(ctx context.Context, cacheKey string) {
	switch CacheType {
	case 1: // MemCache
		gcache.Remove(ctx, cacheKey)
	case 2: // Redis
		g.Redis().Do(ctx, "DEL", cacheKey)
	}
}

// GetCache 根据配置文件里的设置：gToken.system.CacheMode，自动支持MemCache, Redis两种缓存删除。
func GetCache(ctx context.Context, cacheKey string) (interface{}, error) {
	switch CacheType {
	case 1: // MemCache
		return gcache.Get(ctx, cacheKey)
	case 2: // Redis
		return g.Redis().Do(ctx, "GET", cacheKey)
	}
	return nil, errors.New("未知CacheType")
}

// SetCache 根据配置文件里的设置：gToken.system.CacheMode，自动支持MemCache, Redis两种缓存删除。
func SetCache(ctx context.Context, cacheKey string, cacheValue interface{}, timeOut time.Duration) (err error) {
	switch CacheType {
	case 1: // MemCache
		return gcache.Set(ctx, cacheKey, cacheValue, timeOut)
	case 2: // Redis
		value := gconv.String(cacheValue)
		//_, err = g.Redis().DoWithTimeout(timeOut, "SET", cacheKey, value)
		_, err = g.Redis().Do(ctx, "SETEX", cacheKey, value, timeOut) //TommySUN SETEX设置秒，SETPX：millisecond
		return err
	}
	return errors.New("CacheType error")
}

// GetCacheString 获取cache内容
func GetCacheString(ctx context.Context, cacheKey string) (value string, err error) {

	switch CacheType {
	case 1: // MemCache
		cacheValue, err := gcache.Get(ctx, cacheKey)
		return gconv.String(cacheValue), err
	case 2: // Redis
		cacheValue, err := g.Redis().Do(ctx, "GET", cacheKey)
		return gconv.String(cacheValue), err
	}
	return "", errors.New("未知CacheType")

}
